﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using ArgusLib.InteropServices;
using ArgusLib.FFmpeg.avutil;
using uint64_t = System.UInt64;

namespace ArgusLib.FFmpeg.avcodec
{
	public class AVCodec : NativeWrapper<Interop.AVCodecNative>
	{
		#region Methods
		public static AVCodec GetEncoder(AVCodecID codecID)
		{
			return Interop.Functions.avcodec_find_encoder(codecID);
		}

		protected override void DisposeCore()
		{
		}
		#endregion

		#region Properties
		/// <summary>
		/// Name of the codec implementation.
		/// The name is globally unique among encoders and among decoders (but an
		/// encoder and a decoder can share the same name).
		/// This is the primary way to find a codec from the user perspective.
		/// </summary>
		public string Name { get { return this.Structure.name; } }


		/// <summary>
		/// Descriptive name for the codec, meant to be more human readable than name.
		/// You should use the NULL_IF_CONFIG_SMALL() macro to define it.
		/// </summary>
		public string LongName { get { return this.Structure.long_name; } }

		public AVMediaType MediaType { get { return this.Structure.type; } }
		public AVCodecID CodecID { get { return this.Structure.id; } }
		public CodecCapabilities Capabilities { get { return this.Structure.capabilities; } }

		/// <summary>
		/// array of supported framerates, or NULL if any, array is terminated by {0,0}
		/// </summary>
		public AVRational[] SupportedFramerates
		{
			get { return Marshaler.MarshalArray<AVRational>(this.Structure.supported_framerates, new AVRational() { num = 0, den = 0 }); }
		}

		/// <summary>
		/// array of supported pixel formats, or NULL if unknown, array is terminated by -1
		/// </summary>
		public AVPixelFormat[] SupportedPixelFormats
		{
			get { return Marshaler.MarshalArray<AVPixelFormat>(this.Structure.pix_fmts, (AVPixelFormat)(-1)); }
		}

		/// <summary>
		/// array of supported audio samplerates, or NULL if unknown, array is terminated by 0
		/// </summary>
		public int[] SupportedSamplerates
		{
			get { return Marshaler.MarshalArray<int>(this.Structure.supported_samplerates, 0); }
		}

		/// <summary>
		/// array of supported sample formats, or NULL if unknown, array is terminated by -1
		/// </summary>
		public AVSampleFormat[] SupportedSampleFormats
		{
			get { return Marshaler.MarshalArray<AVSampleFormat>(this.Structure.sample_fmts, (AVSampleFormat)(-1)); }
		}

		/// <summary>
		/// array of support channel layouts, or NULL if unknown. array is terminated by 0
		/// </summary>
		public uint64_t[] SupportedChannelLayouts
		{
			get { return Marshaler.MarshalArray<uint64_t>(this.Structure.channel_layouts, 0); }
		}

		///// <summary>
		///// maximum value for lowres supported by the decoder
		///// </summary>
		//public uint8_t max_lowres;

		///// <summary>
		///// AVClass for the private context
		///// </summary>
		///// <CType>const AVClass *</CType>
		//public IntPtr priv_class;

		/// <summary>
		/// array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}
		/// </summary>
		public AVProfile[] Profiles
		{
			get { return Marshaler.MarshalArray<AVProfile>(this.Structure.channel_layouts, new AVProfile() { profile = Interop.FF_PROFILE.FF_PROFILE_UNKNOWN }); }
		}
		#endregion

	}
}
